package kk.json.utils;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import kk.json.Condition;
import kk.json.JSONDb;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

public class JSONUtils {

	private static int	bufferSize	= 1024;

	public static boolean writeJSONArray(JSONArray jsonArray, String path) {
		boolean successful = false;

		File file = new File(path);

		if (file.exists())
			file.delete();

		BufferedWriter writer = null;
		try {
			writer = new BufferedWriter(new FileWriter(file));

			writer.write(jsonArray.toString());

			writer.flush();

			successful = true;

		} catch (IOException e) {
			e.printStackTrace();

			System.out.println("JSONArray 写入失败。 路径：" + path);
		} finally {
			try {
				writer.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

		return successful;
	}

	public static JSONArray readJSONArray(String path) {

		File file = new File(path);

		if (file.exists()) {
			try {
				BufferedReader reader = new BufferedReader(new FileReader(file));

				char[] buffer = new char[bufferSize];
				int hasRead;

				StringBuilder sb = new StringBuilder();
				while ((hasRead = reader.read(buffer)) != -1) {
					sb.append(buffer, 0, hasRead);
				}

				JSONArray jsonArr = new JSONArray(sb.toString());

				if (jsonArr != null)
					return jsonArr;

			} catch (FileNotFoundException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			} catch (JSONException e) {
				e.printStackTrace();
			}
		}

		return new JSONArray();
	}

	/** 查询操作 */
	public static List<JSONObject> queryByCondition(JSONArray jsonArray, Condition condition) {
		List<JSONObject> list = parseJSONArray(jsonArray);
		List<JSONObject> queryList = new ArrayList<JSONObject>();

		if (condition == null) {
			return list;
		}

		for (JSONObject json : list) {
			if (condition != null && condition.onFitrate(json)) {
				queryList.add(json);
			}
		}

		return queryList;
	}

	/**
	 * 将满足条件的元素，从jsonList去除
	 * 
	 * @param jsonArray
	 * @param condition
	 * 
	 * @return 返回已经去除指定jsonObject的JsonArray
	 */
	public static JSONArray remove(JSONArray jsonArray, Condition condition) {

		// 从JSONArray转成List<JSONObject>，便于增删改查操作
		List<JSONObject> jsonList = parseJSONArray(jsonArray);

		jsonList = remove(jsonList, condition);

		// 重新生成一个 JSONArray
		jsonArray = new JSONArray();
		for (JSONObject jsonObject : jsonList) {
			jsonArray.put(jsonObject);
		}

		return jsonArray;
	}

	/**
	 * 将满足条件的元素，从jsonList去除
	 * 
	 * @param jsonList
	 * @param condition
	 * @return 已去除指定元素的{@linkplain List}
	 */
	public static List<JSONObject> remove(List<JSONObject> jsonList, Condition condition) {

		for (int i = 0; i < jsonList.size(); i++) {
			JSONObject jsonObject = jsonList.get(i);

			if (condition.onFitrate(jsonObject)) {
				jsonList.remove(i--);
			}
		}

		return jsonList;
	}

	/**
	 * 更新某个元素
	 * 
	 * @param jsonArray
	 * @param condition
	 */
	public static JSONArray update(JSONArray jsonArray, JSONObject updateJson, Condition condition) {

		// 从JSONArray转成List<JSONObject>，便于增删改查操作
		List<JSONObject> jsonList = parseJSONArray(jsonArray);

		jsonList = update(jsonList, updateJson, condition);

		// 重新生成一个 JSONArray
		jsonArray = new JSONArray();
		for (JSONObject jsonObject : jsonList) {
			jsonArray.put(jsonObject);
		}

		return jsonArray;
	}

	/**
	 * 更新某个元素
	 * 
	 * @param jsonList
	 * @param condition
	 * @return 已去除指定元素的{@linkplain List}
	 */
	public static List<JSONObject> update(List<JSONObject> jsonList, JSONObject updateJson, Condition condition) {

		for (int i = 0; i < jsonList.size(); i++) {
			JSONObject jsonObject = jsonList.get(i);

			if (condition.onFitrate(jsonObject)) {
				jsonList.set(i, updateJson);
			}
		}

		return jsonList;
	}

	/**
	 * {@link JSONArray}转化成{@link List}<{@link JSONObject}>
	 * 
	 * @param jsonArray
	 * @return
	 */
	public static List<JSONObject> parseJSONArray(JSONArray jsonArray) {

		List<JSONObject> jsonList = new ArrayList<JSONObject>();

		for (int i = 0; i < jsonArray.length(); i++) {
			try {
				JSONObject jsonObject = jsonArray.getJSONObject(i);

				if (jsonObject != null)
					jsonList.add(jsonObject);

			} catch (JSONException e) {
				e.printStackTrace();
			}
		}

		return jsonList;
	}

	public static <T> List<T> parseJSONArray(Class<T> clazz, JSONArray jsonArray) {
		List<T> list = new ArrayList<T>();

		for (int i = 0; i < jsonArray.length(); i++) {
			JSONObject json = new JSONObject();
			try {
				json = jsonArray.getJSONObject(i);
			} catch (JSONException e) {
				e.printStackTrace();
			}

			@SuppressWarnings("static-access")
			T t = JSONDb.getInstance().getParser(clazz).parse(json, clazz);
			list.add(t);
		}

		return list;
	}
}
